#region Copyright
/// <copyright>
/// Copyright (c) 2007 Ilia Shramko.
/// Released under the terms of the GNU General Public License.
/// </copyright>
#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;

using Osh.Media;

namespace Osh.ProgDvb
{
	/// <summary>
	/// Summary description for ChannelTree.
	/// </summary>
	public class ChannelTree : MediaTree
	{
		private string _path;
		private int _version;
		private ChannelTreeType _type;

		public ChannelTree(ChannelDatabase database, string channelTreePath)
			: base(database)
		{
			Load(channelTreePath);
		}

		public void Reload()
		{
			Load(_path);
		}

		private void Load(string channelTreePath)
		{
			_path = channelTreePath;
			using(FileStream stream = 
					  new FileStream(channelTreePath, FileMode.Open, FileAccess.Read, FileShare.Read))
			{
				using(BinaryReader reader = new BinaryReader(stream, Encoding.Unicode))
				{
					ReadChannelTree(reader);
				}
			}
		}

		private void ReadChannelTree(BinaryReader reader)
		{
			uint id = reader.ReadUInt32();
			if(id != 0x42DFBC3A)
				throw new ProgDvbException(
					"The ProgDVB channel list specified in the configuration file is corrupted.");

			_version = (int)reader.ReadUInt32();
			if(_version < 0x69)
				throw new ProgDvbException(
					string.Format("Version {0} of the ProgDVB channel list is not supported.\n" + 
						"To update the channel list version please open the channel list properties dialog, " +
						"press OK and than restart ProgDVB application.", _version));
			if(_version > 0x6C)
				throw new ProgDvbException(
					string.Format("Version {0} of the ProgDVB channel list is not supported.\n" +
						"Please upgrade OSH.", _version));

			uint headerSize = reader.ReadUInt32();
			uint fileSize = reader.ReadUInt32();
			uint folderCount = reader.ReadUInt32();
			reader.ReadUInt32(); // m_bRequestForDelete
			_type = (ChannelTreeType)reader.ReadUInt32();
			reader.ReadUInt32(); // m_ChannelTypes * 3
			reader.ReadUInt32();
			reader.ReadUInt32();
			this.Name = reader.ReadString(64);

			reader.BaseStream.Seek(headerSize, SeekOrigin.Begin);

			for(uint i = 0; i < folderCount; i++)
			{
				ChannelFolder folder = new ChannelFolder(this, reader, i.ToString());
				this.FolderList.Add(folder);
			}
		}

		internal ChannelDatabase ChannelDatabase
		{
			get { return (ChannelDatabase)this.Library; }
		}

		public string Path
		{
			get { return _path; }
		}

		public int Version
		{
			get { return _version; }
		}

		public ChannelTreeType Type
		{
			get { return _type; }
		}

		internal bool SupportsDeviceId
		{
			get { return _version >= 0x6A; }
		}

		internal bool SupportsIptv
		{
			get { return _version >= 0x6B; }
		}

		internal int ChannelIdSize
		{
			get
			{
				int size = 16;
				if(this.SupportsDeviceId)
					size += DeviceId.Size;
				if(this.SupportsIptv)
					size += 4;
				return size;
			}
		}
	}
}

